package com.example.klinedemo

import android.content.Context
import android.graphics.Canvas
import android.util.Log
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View
import android.widget.Scroller
import androidx.core.view.GestureDetectorCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleCoroutineScope
import androidx.lifecycle.LifecycleOwner
import com.example.klinedemo.KLineViewBitMapUtil.Companion.DEFAULT_SHOW_K_LINE_COUNT
import com.example.klinedemo.bean.KLineItem
import kotlin.math.abs

class KLineView(
    context: Context,
    override val lifecycle: Lifecycle,
    val lifecycleScope: LifecycleCoroutineScope
) : View(context), LifecycleOwner {
    companion object {
        const val TAG = "KLineView"
    }

    private val bitMapUtil = KLineViewBitMapUtil(this)

    private var klineDataCash: ArrayList<KLineItem> = arrayListOf()

    @Volatile
    private var kLineDrawLeftIndex: Int = 0 // 指针

    @Volatile
    private var kLineDrawRightIndex = 0 // 指针

    // 手势检测器
    private val gestureDetector: GestureDetectorCompat

    // 惯性滑动控制器
    private val scroller: Scroller

    private var isLongPress = false

    init {
        // 初始化手势检测器和Scroller
        gestureDetector = GestureDetectorCompat(context, ScrollGestureListener())
        scroller = Scroller(context)
    }


    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        // 释放旧 Bitmap 防止内存泄漏
        bitMapUtil.recycle()
        // 创建新的bitMap
        bitMapUtil.initBitMap(w, h)
    }


    fun updateValue(klineData: ArrayList<KLineItem>) {
        if (klineData.isEmpty()) return
        klineDataCash = klineData
        kLineDrawLeftIndex = klineData.size - DEFAULT_SHOW_K_LINE_COUNT
        kLineDrawRightIndex = klineData.size
        updateValueBitMap()
    }

    private fun updateValueBitMap() {
        if (kLineDrawLeftIndex <= 0) {
            kLineDrawLeftIndex = 0
            kLineDrawRightIndex = DEFAULT_SHOW_K_LINE_COUNT
        }
        if (kLineDrawRightIndex > klineDataCash.size) {
            kLineDrawLeftIndex = klineDataCash.size - DEFAULT_SHOW_K_LINE_COUNT
            kLineDrawRightIndex = klineDataCash.size
        }

        val subList = klineDataCash.subList(kLineDrawLeftIndex, kLineDrawRightIndex)
        bitMapUtil.drawLine(subList)
        invalidate()
    }

    override fun onDraw(canvas: Canvas) {
        bitMapUtil.onDraw(canvas)
    }

    private var startX =0f;
     private var isFling = false;

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        if (event?.action == MotionEvent.ACTION_DOWN){
            scroller.forceFinished(true);
            startX = event.x
            isFling = false;
        }
        event?.let {
            if (gestureDetector.onTouchEvent(event)){ // gestureDetector.onTouchEvent Down事件有可能会被放进来，所以要把down提到前面去
                Log.d(TAG,"gestureDetector.onTouchEvent = true")
                return true
            }
            Log.d(TAG,"gestureDetector.onTouchEvent = false")
            if (isFling) {
                return true;
            }
        }
        when(event?.action){
            MotionEvent.ACTION_MOVE -> {
                if (isLongPress) {
                    var x = event.x;
                    var y = event.y;
                    flushedKLine()
                    bitMapUtil.drawCrosshairs(x,y)
                }else{
                    // 这里来控制滚动
                    val endX = event.x;
                    if (abs(endX - startX) > bitMapUtil.kLineWidth) {
                        moveKLineByDist(endX - startX,"onTouchEvent")
                        startX = endX;
                    }
                }

            }
            MotionEvent.ACTION_CANCEL->{
                Log.d(TAG,"取消事件执行")
            }
            MotionEvent.ACTION_UP->{
                isLongPress = false
                flushedKLine()
            }
        }

        return true
    }

     private var lastX = 0;

     private var curSum = 0;

    override fun computeScroll() {
        Log.d(TAG,"scroller.computeScrollOffset() = ${scroller.computeScrollOffset()}")
        if (scroller.computeScrollOffset()) {
            val x = scroller.currX;
            Log.d(TAG, "scroller.currX = ${scroller.currX}")
            if (x == scroller.finalX) {
                scroller.forceFinished(true);
                return;
            }
            val diff = x - lastX;
            val w = bitMapUtil.kLineWidth;
            val total = diff + curSum;
            Log.d(TAG, "total = $total")
            if (abs(total) >= w) {
                moveKLineByDist(total.toFloat())
                curSum = (total % w).toInt();
            }else{
                curSum = total;
            }
            lastX = x;
        }
    }


    /**
     * 刷新控制的k线
     */
    private fun flushedKLine(){
        moveKLineByDist(name = "flushedKLine")
    }

    /**
     * 控制展示的k线
     */
    private fun moveKLineByDist(total: Float = 0f,name:String = "") {
        Log.d(TAG,"total = $total name = $name")
        if (total != 0f) {
            val count = ((total) / bitMapUtil.kLineWidth).toInt()
            kLineDrawLeftIndex -= count
            kLineDrawRightIndex -= count
        }
        updateValueBitMap()
    }


    inner class ScrollGestureListener : GestureDetector.SimpleOnGestureListener() {

        override fun onDown(e: MotionEvent): Boolean = true

        override fun onLongPress(e: MotionEvent) {
            Log.d(TAG,"onLongPress e.x = " + e.x)
            isLongPress = true
            var x = e.x;
            var y = e.y;
            bitMapUtil.drawCrosshairs(x,y)
            invalidate()
        }

        override fun onFling(
            e1: MotionEvent?,
            e2: MotionEvent,
            velocityX: Float,
            velocityY: Float
        ): Boolean {
            Log.d(TAG,"执行onFling方法")
            // 触发惯性滑动（水平方向）
            //一次最多滑动两屏 避免触发太多的翻页
            isFling = true; // 开始飞
            scroller.fling(
                0, 0,
                velocityX.toInt(), 0,
                -width * 3, width * 3,
                0, 0
            );
            invalidate() // 只有他

            return true
        }
    }


}